package elec;

import static mathUtils.VecMath.*;
import drawing.DrawableSystem;
import integration.Integrator;
import integration.RungeKutta4;
import processing.core.PApplet;

@SuppressWarnings("serial")
public class ElectroFlakeDemo extends PApplet {
	float graphicsScale = 3f;
	int numLumps = 7;
	int flakesPerLump = 5;
	int numFlakes = numLumps*flakesPerLump;
	float timeStep = 1f;
	float stepsPerFrame = 10;
	
	ElectroFlakeSystem sys;
	Integrator integ;
	DrawableSystem dsys;
	
	void addLump(float ang, float r, float q) {
		float x[] = new float[2];
		vecUnitByAngle(ang, x);
		vecScale(x, r);
		ElectroLump m = new ElectroLump(this, q, 25f, x[0], x[1]);
		sys.addElectroLump(m);
		dsys.add(m);
	}
	
	public void setup() {
		size(400, 400);
		smooth();
		
		float x[] = new float[2];
		float v[] = new float[2];
		
		sys = new ElectroFlakeSystem();
		dsys = new DrawableSystem();
		
		addLump(0, 0, 1.0f*flakesPerLump);
		
		for (int i = 0; i < 6; ++i) {
			addLump(i*1.0f/6f * 2.0f * PI, 20f, 1.0f*flakesPerLump);
		}		
		
		for (int i =0; i<numFlakes; ++i) {
			float ang = random(0, 2*PI);
			float r = 0.25f*width/graphicsScale*random(0.125f, 1f);
			vecUnitByAngle(ang, x);
			vecScale(x, r);
			vecZero(v);
			ElectroFlake f = new ElectroFlake(this, 1, -1, 5f, x[0], x[1],
					v[0], v[1]);
			sys.addElectroFlake(f);
			dsys.add(f);
		}
				
		integ = new RungeKutta4(sys);
		integ.findSlope();
		
	}
	
	void advance() {
		integ.finalizeSlope(timeStep);
		integ.takeFinalStep(timeStep);
		integ.findSlope();
	}
	
	public void draw() {

		for (int i = 0; i < stepsPerFrame; ++i) advance();
		
		translate(width/2, height/2);
		scale(graphicsScale, -graphicsScale);
		background(0,0,0);
		
		dsys.draw();
		
	}
}

